package cn.ly.jvm.loader;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

public class OrderClassLoader extends ClassLoader{
	
	private String rootDir;
	
	public OrderClassLoader(String dir) {
		this.rootDir = dir;
	}
	
	@Override
	public Class<?> loadClass(String className) throws ClassNotFoundException {
		Class re = findClass(className);
		if(re != null){
			return re;
		}
		return super.loadClass(className);//如果自定义加载失败了，则再使用继承的ClassLoader父类的类加载器去加载。
	}
	
	@Override
	protected Class<?> findClass(String className) throws ClassNotFoundException {
		Class clz = this.findLoadedClass(className);//查看是否加载过，如果加载过直接返回，如果没有再继续加载
		if(clz == null){
	        byte[] classData = getClassData(className); 
	        if (classData != null) { 
	            return defineClass(className, classData, 0, classData.length); 
	        }
		}
		return clz;
	}
	
	private byte[] getClassData(String className){
        String path = classNameToPath(className); 
        try { 
            InputStream ins = new FileInputStream(path); 
            ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
            int bufferSize = 4096; 
            byte[] buffer = new byte[bufferSize]; 
            int bytesNumRead = 0; 
            while ((bytesNumRead = ins.read(buffer)) != -1) { 
                baos.write(buffer, 0, bytesNumRead); 
            } 
            return baos.toByteArray(); 
        } catch (IOException e) { 
        	System.out.println("[" + e.getMessage() + "]");
        } 
        return null; 
	}
	
	private String classNameToPath(String className){
        return rootDir + File.separatorChar 
                + className.replace('.', File.separatorChar) + ".class"; 
	}
	
	public static void main(String[] args) throws ClassNotFoundException {
		System.out.println("current class : " + OrderClassLoader.class.getClassLoader());
		System.out.println("TestLoader class : " + TestLoader.class);
		OrderClassLoader myLoader = new OrderClassLoader("E:\\newtest\\workspace\\JavaTest\\bin");
		Class clz = myLoader.loadClass("cn.ly.jvm.loader.TestLoader");
		System.out.println("classloader ==> " + clz.getClassLoader());
		
		ClassLoader cl = myLoader;
		while(cl != null){
			System.out.println(cl);
			cl = cl.getParent();
		}
	}

}
